device tree: correctly ignore unit-address when matching nodes by name
authorDavid Vrabel <david.vrabel@citrix.com>
Thu, 22 Mar 2012 14:26:44 +0000 (14:26 +0000)
committerDavid Vrabel <david.vrabel@citrix.com>
Thu, 22 Mar 2012 14:26:44 +0000 (14:26 +0000)
When matching node by their name, correctly ignore the unit address
(@...) part of the name.  Previously, a "memory-controller" node would
be incorrectly matched as a "memory" node.

Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
Committed-by: Ian Campbell <ian.campbell@citrix.com>
xen/common/device_tree.c

index 4a7166dd65191f4eb0b54184854048a7283da662..5329956279c47481d8a6012d6576a0fbff44f30c 100644 (file)
 struct dt_early_info __initdata early_info;
 void *device_tree_flattened;
 
+static bool_t __init node_matches(const void *fdt, int node, const char *match)
+{
+    const char *name;
+    size_t match_len;
+
+    name = fdt_get_name(fdt, node, NULL);
+    match_len = strlen(match);
+
+    /* Match both "match" and "match@..." patterns but not
+       "match-foo". */
+    return strncmp(name, match, match_len) == 0
+        && (name[match_len] == '@' || name[match_len] == '\0');
+}
+
 static void __init get_val(const u32 **cell, u32 cells, u64 *val)
 {
     *val = 0;
@@ -98,14 +112,11 @@ static void __init early_scan(const void *fdt)
 {
     int node;
     int depth;
-    const char *name;
     u32 address_cells[MAX_DEPTH];
     u32 size_cells[MAX_DEPTH];
 
     for ( node = 0; depth >= 0; node = fdt_next_node(fdt, node, &depth) )
     {
-        name = fdt_get_name(fdt, node, NULL);
-
         if ( depth >= MAX_DEPTH )
         {
             early_printk("fdt: node '%s': nested too deep\n",
@@ -116,9 +127,8 @@ static void __init early_scan(const void *fdt)
         address_cells[depth] = prop_by_name_u32(fdt, node, "#address-cells");
         size_cells[depth] = prop_by_name_u32(fdt, node, "#size-cells");
 
-        if ( strncmp(name, "memory", 6) == 0 )
-            process_memory_node(fdt, node,
-                                address_cells[depth-1], size_cells[depth-1]);
+        if ( node_matches(fdt, node, "memory") )
+            process_memory_node(fdt, node, address_cells[depth-1], size_cells[depth-1]);
     }
 }